package com.avalon.shop.controller;

import com.avalon.core.context.SystemConstant;
import com.avalon.core.exception.FieldCheckException;
import com.avalon.core.model.RecordRow;
import com.avalon.core.redis.RedisCommon;
import com.avalon.core.util.BCryptUtil;
import com.avalon.core.util.ObjectUtils;
import com.avalon.shop.ShopContext;
import com.avalon.shop.service.PetService;
import com.avalon.shop.service.ShareService;
import com.avalon.shop.service.ShopService;
import com.avalon.shop.service.UserService;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/")
public class RootController {
    private final ShopService shopService;
    private final RedisCommon redisCommon;
    private final ShopContext shopContext;
    private final UserService userService;
    private final ShareService shareService;
    private final PetService petService;

    public RootController(ShopService shopService,
                          RedisCommon redisCommon,
                          ShopContext shopContext,
                          UserService userService,
                          ShareService shareService, PetService petService) {
        this.shopService = shopService;
        this.redisCommon = redisCommon;
        this.shopContext = shopContext;
        this.userService = userService;
        this.shareService = shareService;
        this.petService = petService;
    }

    @PostMapping("/login")
    public RecordRow login(@RequestBody Map<String, Object> param) {
        String name = param.get("username").toString();
        String password = param.get("password").toString();
        RecordRow login = shopService.login(name, password);

        if (ObjectUtils.isNull(login) || ObjectUtils.isEmpty(login)) {
            throw new FieldCheckException("账号或密码错误");
        }

        String token = BCryptUtil.simpleUUID();
        login.put("token", token);
        String s = login.convert2Json();
        redisCommon.set("shop_" + SystemConstant.TOKEN_PREFIX + token, s);
        return login;
    }

    @GetMapping("get/file/token")
    public String getFileToken() {
        return shopContext.getBackToken();
    }

    @PostMapping("get/user/thing/count")
    public Map getUserThingCount(@RequestBody Map<String, Object> param) {
        Integer userId = 0;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        return userService.getUserThingCount(userId);
    }

    @PostMapping("/add/user/share")
    public void addUserShare(@RequestBody Map<String, Object> param) {
        Integer userId = 0;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        String openId = "";
        if (param.containsKey("openId")) {
            openId = param.get("openId").toString();
        }
        String shareType = "share";
        if (param.containsKey("shareType")) {
            shareType = param.get("shareType").toString();
        }
        List<Integer> petIds = null;
        if (param.containsKey("petIds") && ObjectUtils.isNotNull(param.get("petIds"))) {
            petIds = (List<Integer>) param.get("petIds");
        }
        String comment = "";
        if (param.containsKey("comment")) {
            comment = param.get("comment").toString();
        }
        List<String> images = null;
        if (param.containsKey("images") && ObjectUtils.isNotNull(param.get("images"))) {
            images = (List<String>) param.get("images");
        }
        String video = null;
        if (param.containsKey("video")) {
            video = param.get("video").toString();
        }
        String sharePrivacyType = "disClose";
        if (param.containsKey("sharePrivacyType")) {
            sharePrivacyType = param.get("sharePrivacyType").toString();
        }
        shareService.addShare(userId, openId,
                shareType,
                petIds,
                comment,
                images,
                video,
                sharePrivacyType);
    }

    @PostMapping("/delete/user/share")
    public void deleteUserShare(@RequestBody RecordRow param) {
        Integer id = 0;
        if (param.isNotNull("id")) {
            id = param.getInteger("id");
        }
        if (id != 0) {
            shareService.deleteModel(id);
        }
    }

    @PostMapping("/get/recommend/share")
    public List<Map> getRecommendShare(@RequestBody Map<String, Object> param) {
        Integer pageNum = 0;
        if (param.containsKey("pageNum")) {
            pageNum = Integer.parseInt(param.get("pageNum").toString());
        }
        Integer pageSize = 0;
        if (param.containsKey("pageSize")) {
            pageSize = Integer.parseInt(param.get("pageSize").toString());
        }
        Integer userId = 0;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        String state = null;
        if (param.containsKey("state")) {
            state = param.get("state").toString();
        }
        return shareService.getRecommendShare(pageNum, pageSize, userId, state);
    }

    @PostMapping("/get/help/share")
    public List<Map> getHelpShare(@RequestBody Map<String, Object> param) {
        Integer pageNum = 0;
        if (param.containsKey("pageNum")) {
            pageNum = Integer.parseInt(param.get("pageNum").toString());
        }
        Integer pageSize = 0;
        if (param.containsKey("pageSize")) {
            pageSize = Integer.parseInt(param.get("pageSize").toString());
        }
        Integer userId = 0;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        String state = null;
        if (param.containsKey("state")) {
            state = param.get("state").toString();
        }
        return shareService.getHelpShare(pageNum, pageSize, userId, state);
    }

    @PostMapping("/get/follow/share")
    public List<Map> getFollowShare(@RequestBody Map<String, Object> param) {
        Integer pageNum = 0;
        if (param.containsKey("pageNum")) {
            pageNum = Integer.parseInt(param.get("pageNum").toString());
        }
        Integer pageSize = 0;
        if (param.containsKey("pageSize")) {
            pageSize = Integer.parseInt(param.get("pageSize").toString());
        }
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        String state = null;
        if (param.containsKey("state")) {
            state = param.get("state").toString();
        }
        return shareService.getFollowShare(pageNum, pageSize, userId, state);
    }

    @PostMapping("/get/user/share")
    public List<Map> getUserShare(@RequestBody Map<String, Object> param) {
        Integer pageNum = 1;
        if (param.containsKey("pageNum")) {
            pageNum = Integer.parseInt(param.get("pageNum").toString());
        }
        Integer pageSize = 10;
        if (param.containsKey("pageSize")) {
            pageSize = Integer.parseInt(param.get("pageSize").toString());
        }
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        String state = null;
        if (param.containsKey("state")) {
            state = param.get("state").toString();
        }
        Integer curUserId = null;
        if (param.containsKey("curUserId")) {
            curUserId = (Integer) param.get("curUserId");
        }
        String sharePrivacyType = null;
        if (param.containsKey("sharePrivacyType")) {
            sharePrivacyType = param.get("sharePrivacyType").toString();
        }
        return shareService.getUserShare(pageNum, pageSize, userId, curUserId, sharePrivacyType, state);
    }


    @PostMapping("/get/share/detail")
    public Map getShareDetail(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        Integer shareId = null;
        if (param.containsKey("shareId")) {
            shareId = Integer.parseInt(param.get("shareId").toString());
        }
        return shareService.getShareDetail(shareId, userId);
    }

    @PostMapping("/like/share")
    public void likeShare(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        Integer shareId = null;
        if (param.containsKey("shareId")) {
            shareId = Integer.parseInt(param.get("shareId").toString());
        }
        Integer thumbUp = 0;
        if (param.containsKey("thumbUp")) {
            thumbUp = Integer.parseInt(param.get("thumbUp").toString());
        }
        shareService.likeShare(userId, shareId, thumbUp);
    }

    @PostMapping("/add/user/follow")
    public void addFollow(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        Integer followId = null;
        if (param.containsKey("followId")) {
            followId = Integer.parseInt(param.get("followId").toString());
        }
        userService.addFollow(userId, followId);
    }

    @PostMapping("/delete/user/follow")
    public void deleteFollow(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        Integer followId = null;
        if (param.containsKey("followId")) {
            followId = Integer.parseInt(param.get("followId").toString());
        }
        userService.deleteFollow(userId, followId);
    }

    @PostMapping("/get/user/detail")
    public Map getUSerDetail(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        return userService.getUserDetail(userId);
    }

    @PostMapping("/get/user/im/id/detail")
    public Map getUSerDetailByImId(@RequestBody Map<String, Object> param) {
        Integer imId = null;
        if (param.containsKey("imId")) {
            imId = Integer.parseInt(param.get("imId").toString());
        }
        return userService.getUserDetailByImId(imId);
    }


    @PostMapping("/update/user/detail")
    public void updateUserDetail(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        String avatar = null;
        if (param.containsKey("avatar")) {
            avatar = param.get("avatar").toString();
        }
        String nickname = null;
        if (param.containsKey("nickname")) {
            nickname = param.get("nickname").toString();
        }
        userService.updateUserDetail(userId, avatar, nickname);
    }


    @PostMapping("/get/user/follow")
    public Map getUserFollow(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        Integer followId = null;
        if (param.containsKey("followId")) {
            followId = Integer.parseInt(param.get("followId").toString());
        }
        return userService.getUserFollow(userId, followId);
    }


    @PostMapping("/share/comment/like")
    public void ShareCommentLike(@RequestBody Map<String, Object> param) {
        Integer shareCommentId = null;
        Integer userId = null;
        Integer like = 0;
        if (param.containsKey("shareCommentId")) {
            shareCommentId = Integer.parseInt(param.get("shareCommentId").toString());
        }
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        if (param.containsKey("like")) {
            like = Integer.parseInt(param.get("like").toString());
        }
        shareService.shareCommentLike(shareCommentId, userId, like);
    }

    @PostMapping("/add/share/comment")
    public Map addShareComment(@RequestBody Map<String, Object> param) {
        Integer shareId = null;
        Integer userId = null;
        String comment = "";
        String image = "";
        Integer relayShareCommentId = null;
        if (param.containsKey("shareId")) {
            shareId = Integer.parseInt(param.get("shareId").toString());
        }
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        if (param.containsKey("comment")) {
            comment = param.get("comment").toString();
        }
        if (param.containsKey("image")) {
            image = param.get("image").toString();
        }
        if (param.containsKey("relayShareCommentId")) {
            relayShareCommentId = Integer.parseInt(param.get("relayShareCommentId").toString());
        }
        return shareService.addShareComment(shareId,
                userId,
                comment,
                image,
                relayShareCommentId);
    }

    @PostMapping("/delete/share/comment")
    public void deleteShareComment(@RequestBody Map<String, Object> param) {
        Integer commentId = null;
        if (param.containsKey("commentId")) {
            commentId = Integer.parseInt(param.get("commentId").toString());
        }
        shareService.deleteShareComment(commentId);
    }

    @PostMapping("/get/share/comment")
    public List<Map> getShareComment(@RequestBody Map<String, Object> param) {
        Integer shareId = null;
        Integer pageNum = 1;
        Integer pageSize = 10;
        Integer userId = null;
        if (param.containsKey("shareId")) {
            shareId = Integer.parseInt(param.get("shareId").toString());
        }
        if (param.containsKey("pageNum")) {
            pageNum = Integer.parseInt(param.get("pageNum").toString());
        }
        if (param.containsKey("pageSize")) {
            pageSize = Integer.parseInt(param.get("pageSize").toString());
        }
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        return shareService.getShareComment(shareId, pageNum, pageSize, userId);
    }


    @PostMapping("/get/share/child/comment")
    public List<Map> getShareChildComment(@RequestBody Map<String, Object> param) {
        Integer rootId = null;
        Integer pageNum = 1;
        Integer pageSize = 10;
        Integer userId = null;
        if (param.containsKey("rootId")) {
            rootId = Integer.parseInt(param.get("rootId").toString());
        }
        if (param.containsKey("pageNum")) {
            pageNum = Integer.parseInt(param.get("pageNum").toString());
        }
        if (param.containsKey("pageSize")) {
            pageSize = Integer.parseInt(param.get("pageSize").toString());
        }
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        return shareService.getChildShareComment(rootId, pageNum, pageSize, userId);
    }

    @PostMapping("/add/user/remind")
    public RecordRow addUserRemind(@RequestBody Map<String, Object> param) {
        String remind = null;
        String date = null;
        String time = null;
        String often = null;
        Integer userId = null;
        List<Integer> petIds = null;
        if (param.containsKey("name")) {
            remind = param.get("name").toString();
        }
        if (param.containsKey("date")) {
            date = param.get("date").toString();
        }
        if (param.containsKey("time")) {
            time = param.get("time").toString();
        }
        if (param.containsKey("often")) {
            often = param.get("often").toString();
        }
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        if (param.containsKey("petIds")) {
            petIds = (List<Integer>) (param.get("petIds"));
        }
        return userService.addUserRemind(remind, date, time, often, userId, petIds);
    }

    @PostMapping("/delete/user/remind")
    public void deleteUserRemind(@RequestBody Map<String, Object> param) {
        Integer remindId = null;
        if (param.containsKey("remindId")) {
            remindId = Integer.parseInt(param.get("remindId").toString());
        }
        userService.deleteUserRemind(remindId);
    }

    @PostMapping("/get/remind/detail")
    public Map getRemindDetail(@RequestBody Map<String, Object> param) {
        Integer id = null;
        if (param.containsKey("id")) {
            id = Integer.parseInt(param.get("id").toString());
        }
        return userService.getRemindDetail(id);
    }

    @PostMapping("/update/user/remind")
    public void updateUserRemind(@RequestBody Map<String, Object> param) {
        Integer id = null;
        String remind = null;
        String date = null;
        String time = null;
        String often = null;
        List<Integer> petIds = null;
        if (param.containsKey("id")) {
            id = Integer.parseInt(param.get("id").toString());
        }
        if (param.containsKey("remind")) {
            remind = param.get("remind").toString();
        }
        if (param.containsKey("date")) {
            date = param.get("date").toString();
        }
        if (param.containsKey("time")) {
            time = param.get("time").toString();
        }
        if (param.containsKey("often")) {
            often = param.get("often").toString();
        }

        if (param.containsKey("petIds")) {
            petIds = (List<Integer>) (param.get("petIds"));
        }
        userService.updateUserRemind(id, remind, date, time, often, petIds);
    }

    @PostMapping("/get/remind/list")
    public List<Map> getRemindList(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        Integer pageNum = null;
        if (param.containsKey("pageNum")) {
            pageNum = Integer.parseInt(param.get("pageNum").toString());
        }
        Integer pageSize = null;
        if (param.containsKey("pageSize")) {
            pageSize = Integer.parseInt(param.get("pageSize").toString());
        }
        return userService.getRemindList(userId, pageNum, pageSize);
    }

    @PostMapping("/done/user/remind")
    public void doneUserRemind(@RequestBody Map<String, Object> param) {
        Integer remindId = null;
        if (param.containsKey("remindId")) {
            remindId = Integer.parseInt(param.get("remindId").toString());
        }
        userService.doneUserRemind(remindId);
    }

    @PostMapping("/add/user/account")
    public RecordRow addUserAccount(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        List<Integer> petIds = null;
        if (param.containsKey("petIds")) {
            petIds = (List<Integer>) param.get("petIds");
        }
        BigDecimal account = null;
        if (param.containsKey("account")) {
            account = new BigDecimal(param.get("account").toString());
        }
        String remark = null;
        if (param.containsKey("remark")) {
            remark = param.get("remark").toString();
        }
        String accountDate = null;
        if (param.containsKey("accountDate")) {
            accountDate = param.get("accountDate").toString();
        }
        String name = null;
        if (param.containsKey("name")) {
            name = param.get("name").toString();
        }
        return userService.addUserAccount(
                name,
                account,
                accountDate,
                remark,
                userId,
                petIds);
    }

    @PostMapping("/get/user/account/list")
    public List<Map> getUserAccountList(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        Integer pageNum = null;
        if (param.containsKey("pageNum")) {
            pageNum = Integer.parseInt(param.get("pageNum").toString());
        }
        Integer pageSize = null;
        if (param.containsKey("pageSize")) {
            pageSize = Integer.parseInt(param.get("pageSize").toString());
        }
        return userService.getUserAccountList(userId, pageNum, pageSize, null, null);
    }

    @PostMapping("/get/user/account/all")
    public List<Map> getUserAccountAll(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        Integer year = null;
        if (param.containsKey("year")) {
            year = Integer.parseInt(param.get("year").toString());
        }
        Integer month = null;
        if (param.containsKey("month")) {
            month = Integer.parseInt(param.get("month").toString());
        }
        return userService.getUserAccountAll(userId, year, month);
    }


    @PostMapping("/get/user/remind/item")
    public List<Map> getUserRemindItem(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        return userService.getUserRemindItem(userId);
    }

    @PostMapping("/get/user/account/item")
    public List<Map> getUserAccountItem(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        return userService.getUserAccountItem(userId);
    }

    @PostMapping("/get/account/sum")
    public Map getSumAccount(@RequestBody Map<String, Object> param) {
        Integer userId = null;
        if (param.containsKey("userId")) {
            userId = Integer.parseInt(param.get("userId").toString());
        }
        Integer year = null;
        if (param.containsKey("year")) {
            year = Integer.parseInt(param.get("year").toString());
        }
        Integer month = null;
        if (param.containsKey("month")) {
            month = Integer.parseInt(param.get("month").toString());
        }
        return userService.getSumAccount(userId, year, month);
    }
}